package com.xique.park.service.command.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.constant.HttpStatus;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.utils.command.CommandResultUtil;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.park.api.IParkCarCommandApi;
import com.xique.park.bean.domain.ParkCar;
import com.xique.park.bean.domain.ParkDeviceNew;
import com.xique.park.constant.CommandConstant;
import com.xique.park.constant.ParkApiName;
import com.xique.park.service.command.service.IParkCarCommandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆命令下发
 *
 * @author: xique
 */
@Service
public class ParkCarCommandServiceImpl extends CommandCommServiceImpl implements IParkCarCommandService {

    @Autowired
    private IParkCarCommandApi parkCarCommandApi;

    private static final String NO_MAIN_DEV = "车场没有添加主相机，无需下发";

    private static final String NO_PARAM = "下发失败，车场参数不能为空";

    @Override
    public AjaxResult downSingleCar(Long parkId, String sn, ParkCar parkCar) {
        List<ParkCar> parkCarList = new ArrayList<>(1);
        parkCarList.add(parkCar);
        return downCars(parkId, sn, parkCarList);
    }

    /**
     * 车场所有设备下载单个车辆信息
     */
    @Override
    public AjaxResult downSingleCar(Long parkId, ParkCar parkCar, String reminderMsg) {
        if (null != parkId) {
            // 查询车场下的所有主设备
            List<ParkDeviceNew> parkDeviceNewList = getMainDevListByParkId(parkId);
            if (CollUtil.isNotEmpty(parkDeviceNewList)) {
                // 所有主设备下发是否成功
                StringBuilder resultMsg = new StringBuilder(reminderMsg).append(Constants.BR);
                for (ParkDeviceNew parkDeviceNew : parkDeviceNewList) {
                    if (StringUtils.isNotEmpty(parkDeviceNew.getCode())) {
                        // 逐个下发
                        AjaxResult result = downSingleCar(parkId, parkDeviceNew.getCode(), parkCar);
                        if (null != result && null != result.get(Constants.MESSAGE)) {
                            String message = (String) result.get(Constants.MESSAGE);
                            resultMsg.append(parkDeviceNew.getName()).append(message).append(Constants.BR);
                        }
                    }
                }
                return AjaxResult.success(resultMsg.toString());
            } else {
                return AjaxResult.success(reminderMsg + NO_MAIN_DEV);
            }
        } else {
            return AjaxResult.commandError(reminderMsg + NO_PARAM);
        }
    }

    @Override
    public AjaxResult delSingleCar(String sn, ParkCar parkCar) {
        JSONObject obj = getBaseObj(parkCar.getParkId(), sn, ParkApiName.COMMAND_CAR_DEL, ParkApiName.VER_1_0);
        String plate = parkCar.getPlate();
        List<String> plateList = Collections.singletonList(plate);
        obj.put(CommandConstant.DATA, JSON.toJSON(plateList));

        @SuppressWarnings("unchecked")
        Map<String, Object> params = JSON.toJavaObject(obj, Map.class);

        AjaxResult commandResult = parkCarCommandApi.delSingleCar(params);
        return CommandResultUtil.handleCommandResult(commandResult, "");
    }

    @Override
    public AjaxResult delSingleCar(Long parkId, ParkCar parkCar, String reminderMsg) {
        if (null != parkId) {
            // 查找车场下的所有主相机
            List<String> devCodes = getMainDeviceCodesByParkId(parkId);
            if (CollUtil.isNotEmpty(devCodes)) {
                boolean commandResult = true;
                StringBuilder errMsg = new StringBuilder();
                for (String devCode : devCodes) {
                    if (StringUtils.isNotEmpty(devCode)) {
                        AjaxResult result = delSingleCar(devCode, parkCar);
                        if (result.get(AjaxResult.CODE_TAG).equals(HttpStatus.ERROR)) {
                            commandResult = false;
                            errMsg.append(result.get(AjaxResult.MSG_TAG)).append("，");
                        }
                    }
                }
                if (commandResult) {
                    return AjaxResult.success(reminderMsg + "下发成功");
                } else {
                    return AjaxResult.commandError(reminderMsg + "下发失败，请重新下发，错误原因：" + errMsg);
                }
            } else {
                return AjaxResult.success(reminderMsg + NO_MAIN_DEV);
            }
        } else {
            return AjaxResult.commandError(reminderMsg + NO_PARAM);
        }
    }

    @Override
    public AjaxResult downCars(Long parkId, String sn, List<ParkCar> list) {
        JSONObject dataObj = new JSONObject();
        dataObj.put(CommandConstant.LIST, list);
        List<Long> recIdList = list.stream().map(ParkCar::getId).collect(Collectors.toList());
        dataObj.put(CommandConstant.REC_IDS, recIdList);

        JSONObject obj = getBaseObj(parkId, sn, ParkApiName.COMMAND_CAR_DOWNLOAD, ParkApiName.VER_2_0);
        obj.put(CommandConstant.DATA, dataObj);

        @SuppressWarnings("unchecked")
        Map<String, Object> params = JSON.toJavaObject(obj, Map.class);

        return parkCarCommandApi.downSingleCar(params);
    }

    @Override
    public AjaxResult downCars(Long parkId, List<ParkCar> list, String reminderMsg) {
        if (null != parkId) {
            List<ParkDeviceNew> parkDeviceNewList = getMainDevListByParkId(parkId);
            if (CollUtil.isNotEmpty(parkDeviceNewList)) {
                StringBuilder resultMsg = new StringBuilder(reminderMsg).append(Constants.BR);
                for (ParkDeviceNew parkDeviceNew : parkDeviceNewList) {
                    if (StringUtils.isNotEmpty(parkDeviceNew.getCode())) {
                        AjaxResult result = downCars(parkId, parkDeviceNew.getCode(), list);
                        if (null != result && null != result.get(Constants.MESSAGE)) {
                            String message = (String) result.get(Constants.MESSAGE);
                            resultMsg.append(parkDeviceNew.getName()).append(message).append(Constants.BR);
                        }
                    }
                }
                return AjaxResult.success(resultMsg.toString());
            } else {
                return AjaxResult.success(reminderMsg + NO_MAIN_DEV);
            }
        } else {
            return AjaxResult.commandError(reminderMsg + NO_PARAM);
        }
    }

    @Override
    public AjaxResult delCars(String sn, List<ParkCar> list) {
        String plateStr = list.stream().map(ParkCar::getPlate).collect(Collectors.joining(","));
        String[] plates = plateStr.split(",");
        List<String> plateList = Arrays.asList(plates);

        JSONObject obj = getBaseObj(SecurityUtils.getParkId(), sn, ParkApiName.COMMAND_CAR_DEL, ParkApiName.VER_1_0);
        obj.put(CommandConstant.DATA, JSON.toJSON(plateList));

        @SuppressWarnings("unchecked")
        Map<String, Object> params = JSON.toJavaObject(obj, Map.class);

        AjaxResult commandResult = parkCarCommandApi.delSingleCar(params);
        return CommandResultUtil.handleCommandResult(commandResult, "");
    }

    @Override
    public AjaxResult delCars(Long parkId, List<ParkCar> list, String reminderMsg) {
        if (null != parkId) {
            List<String> devCodes = getMainDeviceCodesByParkId(parkId);
            if (CollUtil.isNotEmpty(devCodes)) {
                boolean commandResult = true;
                StringBuilder errMsg = new StringBuilder();
                for (String devCode : devCodes) {
                    if (StringUtils.isNotEmpty(devCode)) {
                        AjaxResult result = delCars(devCode, list);
                        if (result.get(AjaxResult.CODE_TAG).equals(HttpStatus.ERROR)) {
                            commandResult = false;
                            errMsg.append(result.get(AjaxResult.MSG_TAG)).append("，");
                        }
                    }
                }
                if (commandResult) {
                    return AjaxResult.success(reminderMsg + "下发成功");
                } else {
                    return AjaxResult.commandError(reminderMsg + "下发失败，请重新下发，错误原因：" + errMsg);
                }
            } else {
                return AjaxResult.success(reminderMsg + NO_MAIN_DEV);
            }
        } else {
            return AjaxResult.commandError(reminderMsg + NO_PARAM);
        }
    }

    @Override
    public JSONObject getCommandStatus(Long parkId, List<Long> recIdList) {
        return getCommandStatus(ParkCar.class.getSimpleName(), parkId, recIdList);
    }

}
